package analysisOfConcurrent.quickcheck;

import java.util.Iterator;
import java.util.List;

public class State {
	
	private List<String> linkedList = null;
	private boolean condition = true;
	private String errorMsg = "";
	private int correctTest = 0;
	private String testMsg = "";
	
	public State(List<String> linkedList){
		this.linkedList = linkedList;
	}
	
	public List<String> getList(){
		return this.linkedList;
	}
	
	public boolean postcondition(){
		if(!condition)
			System.err.println(errorMsg);
		else{
			correctTest++;
			System.out.println(correctTest+" "+testMsg);
		}
		
		return this.condition;
	}
	
	public void command(Call call){
		switch(call.getFunction()){
		case ADD_BY_INDEX:
			testMsg = "Test_ADD_BY_INDEX";
			try{
				int size = linkedList.size();
				linkedList.add(call.getIndex(), call.getElement());
				testMsg = testMsg+"{SizeBegin = "+size+" , AddIndex = "+call.getIndex()+" , AddElement = "+call.getElement();
				if(linkedList.size()>size){
					condition = true;
					testMsg = testMsg + " , SizeEnd = "+linkedList.size()+" , Condition = true }";
				}
				else{ 
					condition = false;
					errorMsg = "Add error";
				}
			}catch(IndexOutOfBoundsException e){
				condition = true;
				testMsg = testMsg +" : Out of Bounds";
			}
			break;
		case GET_BY_INDEX:
			testMsg = "Test_GET";
			try{
				String element = linkedList.get(call.getIndex());
				testMsg = testMsg+"{GetIndex = "+call.getIndex()+" , GetElement = "+element;
				if(element != null){
					condition = true;
					testMsg = testMsg +" , condtition = true }";
				}else {
					condition = false;
					errorMsg = "Get error";
				}
				
			}catch(IndexOutOfBoundsException e){
				condition = true;
				testMsg = testMsg +" : Out of Bounds";
			}
			break;
		case REMOVE_BY_INDEX:
			testMsg = "Test_REMOVE";
			try{
				int size = linkedList.size();
				String element = linkedList.remove(call.getIndex());
				testMsg = testMsg+"{SizeBegin = "+size+" , RemoveIndex = "+call.getIndex()+" , RemoveElement = "+element;
				if(linkedList.size()<size && element != null){
					condition = true;
					testMsg = testMsg + " , SizeEnd = "+linkedList.size()+" , Condition = true }";
				}
				else {
					condition = false;
					errorMsg = "Remove error";
				}
			}catch(IndexOutOfBoundsException e){
				condition = true;
				testMsg = testMsg +" : Out of Bounds";
			}
			break;
		case SIZE:
			testMsg = "Test_SIZE";
			int size = 0;
			Iterator<String> iter = linkedList.iterator();
			while(iter.hasNext()){
				size++;
				iter.next();
			}
			if(size == linkedList.size()){
				condition = true;
				testMsg = testMsg + "{SizeIterator = "+size+" , Size = "+ linkedList.size()+" , Conditon = true }"; 
			}
			else{
				condition = false;
				errorMsg = "Size error";
			}
			break;
		case ADD_BY_ELEMENT:
			testMsg = "Test_ADD_BY_ELEMENT";
				boolean returnV = linkedList.add(call.getElement());
				testMsg = testMsg+"{AddElement = "+call.getElement();
				if(returnV){
					condition = true;
					testMsg = testMsg +" , Condition = true }";
				}
				else{ 
					condition = false;
					errorMsg = "Add error";
				}
			break;
			
		}
	}

}
